<template>
  <div class="star-background">
    <canvas ref="canvasRef"></canvas>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch } from 'vue'

const props = defineProps({
  config: {
    type: Object,
    default: () => ({
      density: 'medium',
      speed: 'slow',
      shooting: false,
      nebula: false,
      trail: false
    })
  }
})

const canvasRef = ref(null)
let ctx = null
let stars = []
let shootingStars = []
let animationId = null

class Star {
  constructor(canvas) {
    this.canvas = canvas
    this.x = Math.random() * canvas.width
    this.y = Math.random() * canvas.height
    this.size = Math.random() * 2
    this.speed = Math.random() * 0.5
    this.opacity = Math.random()
  }

  update() {
    this.opacity += (Math.random() - 0.5) * 0.05
    this.opacity = Math.max(0.3, Math.min(1, this.opacity))
  }

  draw(context) {
    context.save()
    context.fillStyle = `rgba(255, 255, 255, ${this.opacity})`
    context.beginPath()
    context.arc(this.x, this.y, this.size, 0, Math.PI * 2)
    context.fill()
    context.restore()
  }
}

class ShootingStar {
  constructor(canvas) {
    this.canvas = canvas
    this.reset()
  }

  reset() {
    this.x = Math.random() * this.canvas.width
    this.y = 0
    this.length = Math.random() * 80 + 20
    this.speed = Math.random() * 10 + 10
    this.opacity = 1
    this.active = false
  }

  update() {
    if (!this.active) {
      if (Math.random() < 0.001) {
        this.active = true
      }
      return
    }

    this.x += this.speed * 0.7
    this.y += this.speed
    this.opacity -= 0.01

    if (this.y > this.canvas.height || this.opacity <= 0) {
      this.reset()
    }
  }

  draw(context) {
    if (!this.active) return

    context.save()
    const gradient = context.createLinearGradient(
      this.x, this.y,
      this.x - this.length * 0.7, this.y - this.length
    )
    gradient.addColorStop(0, `rgba(255, 255, 255, ${this.opacity})`)
    gradient.addColorStop(1, 'rgba(255, 255, 255, 0)')

    context.strokeStyle = gradient
    context.lineWidth = 2
    context.beginPath()
    context.moveTo(this.x, this.y)
    context.lineTo(this.x - this.length * 0.7, this.y - this.length)
    context.stroke()
    context.restore()
  }
}

const init = () => {
  const canvas = canvasRef.value
  if (!canvas) return

  canvas.width = canvas.offsetWidth
  canvas.height = canvas.offsetHeight
  ctx = canvas.getContext('2d')

  const densityMap = {
    low: 100,
    medium: 200,
    high: 300
  }
  const count = densityMap[props.config.density] || 200

  stars = []
  for (let i = 0; i < count; i++) {
    stars.push(new Star(canvas))
  }

  if (props.config.shooting) {
    shootingStars = []
    for (let i = 0; i < 5; i++) {
      shootingStars.push(new ShootingStar(canvas))
    }
  }
}

const animate = () => {
  if (!ctx || !canvasRef.value) return

  ctx.fillStyle = 'rgba(10, 15, 35, 1)'
  ctx.fillRect(0, 0, canvasRef.value.width, canvasRef.value.height)

  // 绘制星云效果
  if (props.config.nebula) {
    const gradient = ctx.createRadialGradient(
      canvasRef.value.width / 2, canvasRef.value.height / 2, 0,
      canvasRef.value.width / 2, canvasRef.value.height / 2, canvasRef.value.width / 2
    )
    gradient.addColorStop(0, 'rgba(102, 126, 234, 0.1)')
    gradient.addColorStop(0.5, 'rgba(118, 75, 162, 0.05)')
    gradient.addColorStop(1, 'rgba(10, 15, 35, 0)')
    ctx.fillStyle = gradient
    ctx.fillRect(0, 0, canvasRef.value.width, canvasRef.value.height)
  }

  stars.forEach(star => {
    star.update()
    star.draw(ctx)
  })

  if (props.config.shooting) {
    shootingStars.forEach(star => {
      star.update()
      star.draw(ctx)
    })
  }

  animationId = requestAnimationFrame(animate)
}

const handleResize = () => {
  init()
}

onMounted(() => {
  init()
  animate()
  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  if (animationId) {
    cancelAnimationFrame(animationId)
  }
  window.removeEventListener('resize', handleResize)
})

watch(() => props.config, () => {
  init()
}, { deep: true })
</script>

<style scoped>
.star-background {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  background: #0a0f23;
}

canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: block;
}
</style>

